// AppContext.java
package exercise.jslide.jslide.app;

import exercise.jslide.jslide.model.Presentation;
import exercise.jslide.jslide.command.UndoManager;
import exercise.jslide.jslide.model.SlideElement;
import exercise.jslide.jslide.view.MainView;
import javafx.stage.Stage;

/**
 * <p>该类是应用程序的上下文类，用于保存应用程序的全局状态。</p>
 * <p>该类是一个单例类，通过 getInstance 方法获取唯一的实例。</p>
 * <p>该类包含了当前演示文稿对象、撤销管理器、主窗口对象和主视图对象。</p>
 * <p>该类的构造方法是私有的，确保该类是单例模式。</p>
 * <p>该类提供了获取和设置当前演示文稿对象、撤销管理器、主窗口对象和主视图对象的方法。</p>
 * <ul>
 *     <li>currentPresentation：当前正在编辑或展示的演示文稿对象</li>
 *     <li>undoManager：用于管理撤销和重做操作的管理器，来自包exercise.jslide.jslide.command</li>
 *     <li>primaryStage：应用程序的主窗口对象</li>
 *     <li>mainView：应用程序的主视图对象，来自包exercise.jslide.jslide.view</li>
 *     <li>createNewPresentation：创建一个新的演示文稿对象并将其设置为当前演示文稿</li>
 * </ul>
 *
 */
public class AppContext {
    /**
     * instance 用于存储 AppContext 类的唯一实例，确保该类是单例模式。
     */
    private static AppContext instance;
    /**
     * 当前正在编辑或展示的演示文稿对象
     */
    private Presentation currentPresentation;
    /**
     * 用于管理撤销和重做操作的管理器，来自包exercise.jslide.jslide.command
     */
    private UndoManager undoManager;
    /**
     * 应用程序的主窗口对象
     */
    private Stage primaryStage;
    /**
     * 应用程序的主视图对象，来自包exercise.jslide.jslide.view
     */
    private MainView mainView;
    private SlideElement clipboard;

    /**
     * 该构造方法用于初始化 AppContext 类的实例，
     * 同时初始化 undoManager 和 currentPresentation。
     * 该构造方法为私有方法，确保不会被外部实例化
     */
    private AppContext() {
        undoManager = new UndoManager();
        createNewPresentation();
    }

    /**
     * 该方法用于获取 AppContext 类的唯一实例。
     * @return 返回 AppContext 类的唯一实例
     */
    public static AppContext getInstance() {
        if (instance == null) {
            instance = new AppContext();
        }
        return instance;
    }

    /**
     * 创建一个新的演示文稿对象并将其设置为当前演示文稿。
     */
    public void createNewPresentation() {
        currentPresentation = new Presentation();
    }

    /**
     * 得到当前演示文稿对象
     * @return 当前演示文稿对象
     */
    public Presentation getCurrentPresentation() {
        return currentPresentation;
    }

    /**
     * 设置当前的演示文稿对象，传入参数为一个演示文稿
     * @param presentation，
     */
    public void setCurrentPresentation(Presentation presentation) {
        this.currentPresentation = presentation;
    }

    /**
     * 得到撤销管理器
     * @return
     */
    public UndoManager getUndoManager() {
        return undoManager;
    }

    /**
     * 获取窗口主要对象
     * @return
     */
    public Stage getPrimaryStage() {
        return primaryStage;
    }

    /**
     * 重置当前窗口主要对象
     * @param primaryStage
     */
    public void setPrimaryStage(Stage primaryStage) {
        this.primaryStage = primaryStage;
    }

    /**
     * 获取主视图
     * @return
     */
    public MainView getMainView() {
        return mainView;
    }

    /**
     * 重置主视图
     * @param mainView
     */
    public void setMainView(MainView mainView) {
        this.mainView = mainView;
    }

    public void setClipboard(SlideElement selectedElement) {
        clipboard = selectedElement;
    }

    public SlideElement getClipboard() {
        return clipboard;
    }

    public void applyUndo() {
        undoManager.undo();
        getMainView().updateView();
    }

    public void applyRedo() {
        undoManager.redo();
        getMainView().updateView();
    }
}